
#region Imported Namespaces
using System;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Web;
using System.Web.UI;
using System.Web.UI.Design;
using System.Web.UI.WebControls;
#endregion

namespace PHSRAG.WebControls
{
	#region Class SetFocus
	/// <summary>
	/// The SetFocus control allows a page to set focus to any control within the same naming container.
	/// The focus persists on that control even through postback.
	/// </summary>
	/// <remarks>
	/// Any page which would like to explicitly set focus to a control would typically include the SetFocus
	/// control and set the control to receive focus using the FocusControl property.
	/// </remarks>
	/// <example>
	/// <p>The following example shows how the page would use this control. The registration of the control can be done
	/// simply by dropping the control on the page in design mode.</p>
	/// <p>Notice the setting of the <b>FocusControl</b> property to the ID of a TextBox control.</p>
	/// <code>
	/// <![CDATA[
	/// <%@ Register TagPrefix="cc1" Namespace="PHSRAG.WebControls" Assembly="PHSRAG.WebControls" %>
	/// ...
	/// <body>
	/// ...
	/// <cc1:SetFocus id="setFocus" runat="server" FocusControl="lastName"></cc1:SetFocus>
	/// <asp:TextBox ID="firstName" Runat="server">Bihari</asp:TextBox>
	/// <asp:TextBox ID="lastName" Runat="server">Srinivasan</asp:TextBox>
	/// ...
	/// </body>
	/// ]]>
	/// </code>
	/// </example>
	[ToolboxData("<{0}:SetFocus runat=server />"), Designer(typeof(SetFocusDesigner))]
	public class SetFocus : System.Web.UI.WebControls.WebControl
	{
		#region Constants
		private const string FocusControlKey = "focusControl_853CDB66-5809-4870-AB19-F93EF624282E";
		private const string ScriptKey = "scriptKey_853CDB66-5809-4870-AB19-F93EF624282E";
		#endregion

		/// <summary>
		/// Get/Set the control which will receive focus.
		/// </summary>
		[Description("Get/Set the control which will receive focus"), Bindable(true), Category("Behavior")]
		public string FocusControl 
		{
			get 
			{
				if (IsDesignMode)
					return string.Empty;

				string s = ViewState[FocusControlKey] as string;
				return (s != null) ? s : string.Empty;
			}
			set 
			{
				if (!IsDesignMode)
					ViewState[FocusControlKey] = value;
			}
		}

		#region Private Properties
		private static bool IsDesignMode	{ get { return HttpContext.Current == null; } }
		#endregion

		#region Overrides
		/// <summary>
		/// If a control is set to receive focus, register client-side javascript to manage the focus.
		/// </summary>
		/// <param name="e">Argument associated with the event</param>
		protected override void OnPreRender(EventArgs e)
		{
			base.OnPreRender(e);

			if (!IsDesignMode)
			{
				Control focusReceiver = NamingContainer.FindControl(FocusControl);
				if (focusReceiver != null)
					RegisterClientScripts(focusReceiver);
			}
		}
		#endregion

		#region Private Methods
		/// <summary>
		/// Register client-side javascript to set focus to the specified control.
		/// </summary>
		/// <param name="focusReceiver"></param>
		private void RegisterClientScripts(Control focusReceiver) 
		{
            if (!Page.ClientScript.IsClientScriptBlockRegistered(ScriptKey)) 
			{
				const string script =
					"<script language='javascript'>\n" +
					"function SetFocus(id)\n" +
					"{\n" +
					"\ttry\n" +
					"\t{\n" +
					"\t\tvar focusReceiver = document.getElementById(id);\n" +
					"\t\tif (focusReceiver != null)\n" +
					"\t\t\tfocusReceiver.focus();\n" +
					"\t}\n" +
					"\tcatch(e)\n" +
					"\t{\n" +
					"\t}\n" +
					"}\n" +
					"</script>\n";

                Page.ClientScript.RegisterClientScriptBlock(GetType(), ScriptKey, script);
			}

            if (!Page.ClientScript.IsStartupScriptRegistered(ScriptKey))
			{
				string script = string.Format(
						  "<script language='javascript'>\n" +
						  "SetFocus('{0}');\n" +
						  "</script>\n", focusReceiver.ClientID);

                Page.ClientScript.RegisterStartupScript(GetType(), ScriptKey, script);
			}
		}
		#endregion
	}
	#endregion

	#region Class SetFocusDesigner
	/// <summary>
	/// <exclude/>
	/// Designer for the PostbackGuard control.
	/// </summary>
	/// <remarks>
	/// This class cannot be used directly.
	/// </remarks>
	public class SetFocusDesigner : ControlDesigner 
	{
		#region Overrides
		/// <summary>
		/// <exclude/>
		/// Return the place-holder HTML.
		/// </summary>
		/// <returns>HTML to render at design time</returns>
		public override string GetDesignTimeHtml() 
		{
			return CreatePlaceHolderDesignTimeHtml();
		}
		#endregion
	}
	#endregion
}

// --- EOF ---
